home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Scene Storm
/
Scene Storm - Volume 1.iso
/
coding
/
c
/
fp_adpcm
/
x2adpcm
/
source
/
x2adpcm.c
< prev
Wrap
C/C++ Source or Header
|
1995-08-25
|
5KB
|
214 lines
/* Convert any known sample format (datatypes!) to ADPCM */
/* Written in 1995 by Christian Buchner. This is Public Domain */
/* Includes */
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/datatypes.h>
#include <clib/alib_stdio_protos.h>
#include <libraries/dos.h>
#include <intuition/intuition.h>
#include <exec/io.h>
#include <exec/memory.h>
#include <exec/execbase.h>
#include <datatypes/datatypes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/soundclass.h>
#include <string.h>
#include <stdarg.h>
/*******************************************************************************/
extern __asm ULONG CompressADPCM2( register __a0 UBYTE *Source,
register __d0 ULONG Length,
register __a1 UBYTE *Destination,
register __d1 ULONG JoinCode );
extern __asm ULONG CompressADPCM3( register __a0 UBYTE *Source,
register __d0 ULONG Length,
register __a1 UBYTE *Destination,
register __d1 ULONG JoinCode );
/*******************************************************************************/
#define INPUT_SIZE 16384
/* Library bases */
struct DosLibrary *DOSBase;
struct Library *DataTypesBase;
struct IntuitionBase *IntuitionBase;
UBYTE *Template="FROM/A,TO/K/A,BITS/K/N";
struct ArgArray
{
UBYTE *aa_From;
UBYTE *aa_To;
ULONG *aa_Bits;
};
struct ArgArray AA;
struct RDArgs *RDArgs;
UBYTE ProgName[60];
/*******************************************************************************/
/* void __saveds main() */
LONG __saveds main()
{
ULONG Bits=2;
if (DOSBase=(struct DosLibrary*)OpenLibrary("dos.library",37))
{
if (DataTypesBase=OpenLibrary("datatypes.library",39))
{
if (!GetProgramName(ProgName,sizeof(ProgName))) strcpy(ProgName,"CDRipper");
if (!(RDArgs=ReadArgs(Template,(LONG *)&AA,0)))
{
PrintFault(IoErr(),ProgName);
}
else
{
if (AA.aa_Bits) Bits= *AA.aa_Bits;
if (Bits != 2 && Bits != 3)
{
Printf("Illegal bit number. Use 2 for ADPCM2 and 3 for ADPCM3.\n");
}
else
{
Object *Sound;
if (Sound=NewDTObject(AA.aa_From, DTA_GroupID, GID_SOUND, TAG_DONE))
{
UBYTE *Sample;
ULONG Length;
ULONG Period;
if (GetDTAttrs(Sound, SDTA_Sample, &Sample, SDTA_SampleLength, &Length, SDTA_Period, &Period, TAG_DONE) != 3)
{
Printf("Cannot get sample attributes!\n");
}
else
{
UBYTE *ADPCMBuffer;
ULONG ADPCMLen;
if (Bits==2) ADPCMLen=(INPUT_SIZE+3)/4;
if (Bits==3) ADPCMLen=(INPUT_SIZE+7)/8*3;
if (!(ADPCMBuffer=AllocVec(ADPCMLen,MEMF_ANY|MEMF_CLEAR)))
{
Printf("No memory for ADPCM buffer!\n");
}
else
{
BPTR OutFile;
if (!(OutFile=Open(AA.aa_To,MODE_NEWFILE)))
{
Printf("Cannot open '%s' for output: ",AA.aa_To);
PrintFault(IoErr(),NULL);
}
else
{
ULONG Frequency=(*(struct ExecBase**)(4))->ex_EClockFrequency*5/Period;
ULONG Offset;
ULONG JoinCode=0;
if (Bits==2) Write(OutFile,"ADPCM2", 6);
if (Bits==3) Write(OutFile,"ADPCM3", 6);
Write(OutFile,&Frequency, sizeof(Frequency));
for (Offset=0; Offset<Length; )
{
ULONG Left=Length-Offset;
ULONG Do = Left < INPUT_SIZE ?
Left : INPUT_SIZE;
Printf("\rCompressing/Saving (%02ld%%)",100*Offset/Length);
if (Bits==2) ADPCMLen=(Do+3)/4;
if (Bits==3) ADPCMLen=(Do+7)/8*3;
if (Bits==2) JoinCode=CompressADPCM2(Sample+Offset, Do, ADPCMBuffer, JoinCode);
if (Bits==3) JoinCode=CompressADPCM3(Sample+Offset, Do, ADPCMBuffer, JoinCode);
Write(OutFile, ADPCMBuffer, ADPCMLen);
Offset+=Do;
if (CheckSignal(SIGBREAKF_CTRL_C))
{
PrintFault(ERROR_BREAK,NULL);
break;
}
}
Printf("\rCompressing/Saving finished\n",100*(Length-Offset)/Length);
Close(OutFile);
}
FreeVec(ADPCMBuffer);
}
}
DisposeDTObject(Sound);
}
else
{
LONG Error=IoErr();
if (Error>=2000)
{
Printf("%s: %s\n",AA.aa_From,GetDTString(Error));
}
else
{
PrintFault(Error, AA.aa_From);
}
}
}
FreeArgs(RDArgs);
}
CloseLibrary(DataTypesBase);
}
CloseLibrary(DOSBase);
}
}
/*******************************************************************************/
/* Show a message to the user */
void __stdargs Message(UBYTE *Msg,...)
{
va_list Arg;
struct EasyStruct Req={sizeof(struct EasyStruct),0,"X2ADPCM message",0,"Okay"};
Req.es_TextFormat=Msg;
va_start(Arg,Msg);
if (IntuitionBase)
{
EasyRequestArgs(NULL,&Req,0,Arg);
}
else
{
VPrintf(Msg,Arg);
Printf("\n");
}
va_end(Arg);
}